package com.demo.ocr.filtering;

import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.util.Arrays;
import java.util.Objects;

import static com.demo.ocr.filtering.ImageUtil.readImg;
import static com.demo.ocr.filtering.ImageUtil.writeImg;

/**
 * @author: 李德才
 * @description:
 * @create: 2021-06-06 16:14
 **/


/**
 * *** 中值滤波 ***
 *
 *  中值滤波方法是，对待处理的当前像素，选择一个模板，该模板为其邻近的若干个像素组成，对模板的像素由小到大进行排序，再用模板的中值来替代原像素的值的方法
 *  优点：抑制效果很好，画面的清析度基本保持；
 *  缺点：对高斯噪声的抑制效果不是很好。
 **/


public class MedianFiltering {

    public static void main(String[] args) {
        medianFiltering("F:\\OCR\\微信截图_20210605171455.png", "F:\\OCR\\微信截图_20210605171455-3.png", "png");
    }

    /**
     * 中值滤波
     *
     * @param srcPath  图片的存储位置
     * @param destPath 图像要保存的存储位置
     * @param format   图像要保存的存储位置
     */
    public static void medianFiltering(String srcPath, String destPath, String format) {
        BufferedImage img = readImg(srcPath);
        int w = Objects.requireNonNull(img).getWidth();
        int h = img.getHeight();
        int[] pix = new int[w * h];
        img.getRGB(0, 0, w, h, pix, 0, w);
        int[] newPix = medianFiltering(pix, w, h);
        img.setRGB(0, 0, w, h, newPix, 0, w);
        writeImg(img, format, destPath);
    }

    /**
     * 中值滤波
     *
     * @param pix 像素矩阵数组
     * @param w   矩阵的宽
     * @param h   矩阵的高
     * @return 处理后的数组
     */
    public static int[] medianFiltering(int[] pix, int w, int h) {
        int[] newPix = new int[w * h];
        int[] temp = new int[9];
        ColorModel cm = ColorModel.getRGBdefault();
        int r = 0;
        for (int y = 0; y < h; y++) {
            for (int x = 0; x < w; x++) {
                if (x != 0 && x != w - 1 && y != 0 && y != h - 1) {
                    temp[0] = cm.getRed(pix[x - 1 + (y - 1) * w]);
                    temp[1] = cm.getRed(pix[x + (y - 1) * w]);
                    temp[2] = cm.getRed(pix[x + 1 + (y - 1) * w]);
                    temp[3] = cm.getRed(pix[x - 1 + (y) * w]);
                    temp[4] = cm.getRed(pix[x + (y) * w]);
                    temp[5] = cm.getRed(pix[x + 1 + (y) * w]);
                    temp[6] = cm.getRed(pix[x - 1 + (y + 1) * w]);
                    temp[7] = cm.getRed(pix[x + (y + 1) * w]);
                    temp[8] = cm.getRed(pix[x + 1 + (y + 1) * w]);
                    Arrays.sort(temp);
                    r = temp[4];
                    newPix[y * w + x] = 255 << 24 | r << 16 | r << 8 | r;
                } else {
                    newPix[y * w + x] = pix[y * w + x];
                }
            }
        }
        return newPix;
    }
}
